// - 用户基本CRUD操作
// - 用户角色管理功能
// - 表级权限管理功能
// - 数据库级权限管理功能
// - 权限检查功能

import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { DatabaseAccess } from '@/entity/DatabaseAccess';
import { Permission } from '@/entity/Permission';
import { Role } from '@/entity/Role';
import { TableAccess } from '@/entity/TableAccess';
import { User } from '@/entity/User';
import { UserRole } from '@/entity/UserRole';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User)
    private userRepository: Repository<User>,
    @InjectRepository(Role)
    private roleRepository: Repository<Role>,
    @InjectRepository(Permission)
    private permissionRepository: Repository<Permission>,
    @InjectRepository(UserRole)
    private userRoleRepository: Repository<UserRole>,
    @InjectRepository(TableAccess)
    private tableAccessRepository: Repository<TableAccess>,
    @InjectRepository(DatabaseAccess)
    private databaseAccessRepository: Repository<DatabaseAccess>,
  ) {}

  // 用户相关操作
  async getUsers() {
    try {
      const users = await this.userRepository.find();
      return {
        code: 0,
        data: users,
        msg: '请求用户列表成功！',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: [],
        msg: `获取用户列表失败: ${errMsg}`,
      };
    }
  }

  async getUserById(id: number) {
    try {
      const user = await this.userRepository.findOne({ where: { id } });
      if (!user) {
        throw new NotFoundException(`ID为${id}的用户不存在`);
      }
      return {
        code: 0,
        data: user,
        msg: '获取用户成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: errMsg,
      };
    }
  }

  async addUser(userData: Partial<User>) {
    try {
      const newUser = this.userRepository.create(userData);
      const savedUser = await this.userRepository.save(newUser);
      return {
        code: 0,
        data: savedUser,
        msg: '添加用户成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `添加用户失败: ${errMsg}`,
      };
    }
  }

  async updateUser(id: number, userData: Partial<User>) {
    try {
      const user = await this.userRepository.findOne({ where: { id } });
      if (!user) {
        throw new NotFoundException(`ID为${id}的用户不存在`);
      }

      await this.userRepository.update(id, userData);
      const updatedUser = await this.userRepository.findOne({ where: { id } });

      return {
        code: 0,
        data: updatedUser,
        msg: '更新用户成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `更新用户失败: ${errMsg}`,
      };
    }
  }

  async deleteUser(id: number) {
    try {
      const user = await this.userRepository.findOne({ where: { id } });
      if (!user) {
        throw new NotFoundException(`ID为${id}的用户不存在`);
      }

      await this.userRepository.delete(id);
      return {
        code: 0,
        data: null,
        msg: '删除用户成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `删除用户失败: ${errMsg}`,
      };
    }
  }

  // 用户角色相关操作
  async assignRoleToUser(userId: number, roleId: number) {
    try {
      // 检查用户和角色是否存在
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const role = await this.roleRepository.findOne({ where: { id: roleId } });
      if (!role) {
        throw new NotFoundException(`ID为${roleId}的角色不存在`);
      }

      // 检查是否已经分配过该角色
      const existingUserRole = await this.userRoleRepository.findOne({
        where: { UserId: userId, RoleId: roleId },
      });

      if (existingUserRole) {
        return {
          code: 0,
          data: existingUserRole,
          msg: '该角色已分配给用户',
        };
      }

      // 创建新的用户角色关联
      const userRole = this.userRoleRepository.create({
        UserId: userId,
        RoleId: roleId,
        user,
        role,
      });

      await this.userRoleRepository.save(userRole);

      return {
        code: 0,
        data: userRole,
        msg: '角色分配成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `角色分配失败: ${errMsg}`,
      };
    }
  }

  async removeRoleFromUser(userId: number, roleId: number) {
    try {
      const userRole = await this.userRoleRepository.findOne({
        where: { UserId: userId, RoleId: roleId },
      });

      if (!userRole) {
        throw new NotFoundException(
          `未找到用户ID为${userId}和角色ID为${roleId}的关联`,
        );
      }

      await this.userRoleRepository.remove(userRole);

      return {
        code: 0,
        data: null,
        msg: '移除角色成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `移除角色失败: ${errMsg}`,
      };
    }
  }

  async getUserRoles(userId: number) {
    try {
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const userRoles = await this.userRoleRepository.find({
        where: { UserId: userId },
        relations: ['role'],
      });

      const roles = userRoles.map((ur) => ur.role);

      return {
        code: 0,
        data: roles,
        msg: '获取用户角色成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: [],
        msg: `获取用户角色失败: ${errMsg}`,
      };
    }
  }

  // 表级权限相关操作
  async assignTableAccessToUser(
    userId: number,
    permissionId: number,
    databaseName: string,
    tableName: string,
  ) {
    try {
      // 检查用户和权限是否存在
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const permission = await this.permissionRepository.findOne({
        where: { id: permissionId },
      });
      if (!permission) {
        throw new NotFoundException(`ID为${permissionId}的权限不存在`);
      }

      // 检查是否已经分配过该表权限
      const existingTableAccess = await this.tableAccessRepository.findOne({
        where: {
          UserId: userId,
          PermissionId: permissionId,
          databaseName,
          tableName,
        },
      });

      if (existingTableAccess) {
        return {
          code: 0,
          data: existingTableAccess,
          msg: '该表权限已分配给用户',
        };
      }

      // 创建新的表级权限
      const tableAccess = this.tableAccessRepository.create({
        UserId: userId,
        PermissionId: permissionId,
        databaseName,
        tableName,
        user,
        permission,
      });

      await this.tableAccessRepository.save(tableAccess);

      return {
        code: 0,
        data: tableAccess,
        msg: '表权限分配成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `表权限分配失败: ${errMsg}`,
      };
    }
  }

  async removeTableAccessFromUser(
    userId: number,
    permissionId: number,
    databaseName: string,
    tableName: string,
  ) {
    try {
      const tableAccess = await this.tableAccessRepository.findOne({
        where: {
          UserId: userId,
          PermissionId: permissionId,
          databaseName,
          tableName,
        },
      });

      if (!tableAccess) {
        throw new NotFoundException(`未找到指定的表权限关联`);
      }

      await this.tableAccessRepository.remove(tableAccess);

      return {
        code: 0,
        data: null,
        msg: '移除表权限成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `移除表权限失败: ${errMsg}`,
      };
    }
  }

  async getUserTableAccess(userId: number) {
    try {
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const tableAccess = await this.tableAccessRepository.find({
        where: { UserId: userId },
        relations: ['permission'],
      });

      return {
        code: 0,
        data: tableAccess,
        msg: '获取用户表权限成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: [],
        msg: `获取用户表权限失败: ${errMsg}`,
      };
    }
  }

  // 数据库级权限相关操作
  async assignDatabaseAccessToUser(
    userId: number,
    permissionId: number,
    databaseName: string,
  ) {
    try {
      // 检查用户和权限是否存在
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const permission = await this.permissionRepository.findOne({
        where: { id: permissionId },
      });
      if (!permission) {
        throw new NotFoundException(`ID为${permissionId}的权限不存在`);
      }

      // 检查是否已经分配过该数据库权限
      const existingDatabaseAccess =
        await this.databaseAccessRepository.findOne({
          where: {
            UserId: userId,
            PermissionId: permissionId,
            databaseName,
          },
        });

      if (existingDatabaseAccess) {
        return {
          code: 0,
          data: existingDatabaseAccess,
          msg: '该数据库权限已分配给用户',
        };
      }

      // 创建新的数据库级权限
      const databaseAccess = this.databaseAccessRepository.create({
        UserId: userId,
        PermissionId: permissionId,
        databaseName,
        user,
        permission,
      });

      await this.databaseAccessRepository.save(databaseAccess);

      return {
        code: 0,
        data: databaseAccess,
        msg: '数据库权限分配成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `数据库权限分配失败: ${errMsg}`,
      };
    }
  }

  async removeDatabaseAccessFromUser(
    userId: number,
    permissionId: number,
    databaseName: string,
  ) {
    try {
      const databaseAccess = await this.databaseAccessRepository.findOne({
        where: {
          UserId: userId,
          PermissionId: permissionId,
          databaseName,
        },
      });

      if (!databaseAccess) {
        throw new NotFoundException(`未找到指定的数据库权限关联`);
      }

      await this.databaseAccessRepository.remove(databaseAccess);

      return {
        code: 0,
        data: null,
        msg: '移除数据库权限成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: null,
        msg: `移除数据库权限失败: ${errMsg}`,
      };
    }
  }

  async getUserDatabaseAccess(userId: number) {
    try {
      const user = await this.userRepository.findOne({ where: { id: userId } });
      if (!user) {
        throw new NotFoundException(`ID为${userId}的用户不存在`);
      }

      const databaseAccess = await this.databaseAccessRepository.find({
        where: { UserId: userId },
        relations: ['permission'],
      });

      return {
        code: 0,
        data: databaseAccess,
        msg: '获取用户数据库权限成功',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: [],
        msg: `获取用户数据库权限失败: ${errMsg}`,
      };
    }
  }

  // 检查用户是否有特定表的特定权限
  async checkUserTablePermission(
    userId: number,
    databaseName: string,
    tableName: string,
    action: string,
  ) {
    try {
      // 查找对应action的权限ID
      const permission = await this.permissionRepository.findOne({
        where: { action },
      });

      if (!permission) {
        return {
          code: 1,
          data: { hasPermission: false },
          msg: `未找到${action}操作的权限定义`,
        };
      }

      // 检查用户是否直接拥有表级权限
      const tableAccess = await this.tableAccessRepository.findOne({
        where: {
          UserId: userId,
          PermissionId: permission.id,
          databaseName,
          tableName,
        },
      });

      if (tableAccess) {
        return {
          code: 0,
          data: { hasPermission: true, source: 'table_access' },
          msg: '用户拥有表级权限',
        };
      }

      // 检查用户是否拥有数据库级权限
      const databaseAccess = await this.databaseAccessRepository.findOne({
        where: {
          UserId: userId,
          PermissionId: permission.id,
          databaseName,
        },
      });

      if (databaseAccess) {
        return {
          code: 0,
          data: { hasPermission: true, source: 'database_access' },
          msg: '用户拥有数据库级权限',
        };
      }

      // 检查用户通过角色是否拥有权限
      // 获取用户的所有角色
      const userRoles = await this.userRoleRepository.find({
        where: { UserId: userId },
      });

      if (userRoles.length > 0) {
        const roleIds = userRoles.map((ur) => ur.RoleId);

        // 检查这些角色是否有对应的权限
        const rolePermissions = await this.roleRepository
          .createQueryBuilder('role')
          .innerJoin('role.permissions', 'permission')
          .where('role.id IN (:...roleIds)', { roleIds })
          .andWhere('permission.id = :permissionId', {
            permissionId: permission.id,
          })
          .getCount();

        if (rolePermissions > 0) {
          return {
            code: 0,
            data: { hasPermission: true, source: 'role_permission' },
            msg: '用户通过角色拥有权限',
          };
        }
      }

      return {
        code: 0,
        data: { hasPermission: false },
        msg: '用户没有所需权限',
      };
    } catch (error: unknown) {
      const errMsg = error instanceof Error ? error.message : '未知错误';
      return {
        code: 1,
        data: { hasPermission: false },
        msg: `检查权限失败: ${errMsg}`,
      };
    }
  }
}
